iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
Kubernetes

探討k8s部署方式系列 第 3

負載平衡[Day3]

  • 分享至 

  • xImage
  •  

十四、Load Balancer:當一台 Backend 不夠用時

前面介紹的前後端分離架構,Backend 仍然只有一台 Server。

例如:

Browser
   │
   ▼
Frontend
   │
   ▼
Backend Server
   │
   ▼
Database

如果使用者數量增加,所有 API Request 都集中在同一台 Backend Server 上,就可能開始出現問題。

例如:

  • CPU 使用率過高
  • Memory 不足
  • Request 排隊
  • API Response 變慢
  • 單台 Server 故障後整個服務中斷

此時就可以把 Backend 從一台增加成多台。

Backend 1
Backend 2
Backend 3

但新的問題是:

Browser 到底要把 Request 傳給哪一台 Backend?

這就是 Load Balancer 要處理的事情。

十五、什麼是 Load Balancer?

Load Balancer 中文通常稱為「負載平衡器」。

它會位於使用者與多台 Backend Server 之間,負責接收 Request,再將 Request 分配到不同 Server。

架構可以簡化為:

                 Browser
                    │
                    ▼
              Load Balancer
                    │
          ┌─────────┼─────────┐
          │         │         │
          ▼         ▼         ▼
      Backend 1 Backend 2 Backend 3

對 Browser 而言,它不需要知道後面到底有幾台 Backend。

Browser 只需要呼叫:

https://api.example.com

真正的 Server 分配工作由 Load Balancer 負責。

例如:

Request 1 → Backend 1
Request 2 → Backend 2
Request 3 → Backend 3
Request 4 → Backend 1

因此 Load Balancer 就像一個流量入口。

十六、為什麼需要 Load Balancer?

最直接的原因是讓系統可以做「水平擴充」。

原本只有:

Backend Server

CPU 80%
Memory 85%

如果單純升級這台機器:

4 Core → 8 Core
8 GB RAM → 16 GB RAM

這稱為:

Vertical Scaling(垂直擴充)

也就是把同一台 Server 變得更強。

另一種方式則是增加機器:

Backend 1
Backend 2
Backend 3

這稱為:

Horizontal Scaling(水平擴充)

Load Balancer 就是水平擴充時非常重要的一環。

十七、完整請求流程

假設目前 Backend 有三台:

Backend 1: 10.0.0.11:8000
Backend 2: 10.0.0.12:8000
Backend 3: 10.0.0.13:8000

使用者呼叫:

GET https://api.example.com/products

Request 不會直接進到某一台 FastAPI,而是先到 Load Balancer。

Browser
   │
   │ GET /products
   ▼
Load Balancer
   │
   ▼
Backend 2
   │
   ▼
FastAPI
   │
   ▼
Database

FastAPI 處理完成後回傳 JSON:

{
  "data": [
    {
      "id": 1,
      "name": "Product A"
    }
  ]
}

Response 再沿原路回去:

Database
   │
   ▼
FastAPI
   │
   ▼
Load Balancer
   │
   ▼
Browser

因此 Load Balancer 的完整角色就是:

Client Request
      │
      ▼
Load Balancer
      │
      ├── Backend 1
      ├── Backend 2
      └── Backend 3

十八、Load Balancer 怎麼決定要送到哪一台?

最常見的方法之一叫做:

Round Robin

也就是輪流分配。

例如:

Request 1 → Backend 1
Request 2 → Backend 2
Request 3 → Backend 3
Request 4 → Backend 1
Request 5 → Backend 2

如果三台機器效能差不多,這是一個很直覺的方式。

另外還有其他策略。

例如:

Least Connections

把新的 Request 分配給目前連線數最少的 Server。

Backend 1 → 100 connections
Backend 2 → 40 connections
Backend 3 → 70 connections

New Request
      │
      ▼
Backend 2

因為 Backend 2 目前比較空閒。

另外還可能使用:

  • IP Hash
  • Weighted Round Robin
  • Least Response Time

不同策略適合不同場景。

十九、Nginx 本身就可以當 Load Balancer

Nginx 不只是 Reverse Proxy,也可以直接做到 Load Balancing。

例如:

upstream backend_servers {
    server 10.0.0.11:8000;
    server 10.0.0.12:8000;
    server 10.0.0.13:8000;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_servers;
    }
}

其中:

upstream backend_servers

就是定義一組 Backend Server。

10.0.0.11:8000
10.0.0.12:8000
10.0.0.13:8000

當 Request 進來:

api.example.com/products

Nginx 就會從這三台 Server 中選一台處理。

整個架構就是:

                   Internet
                      │
                      ▼
               Nginx Load Balancer
                      │
            ┌─────────┼─────────┐
            │         │         │
            ▼         ▼         ▼
        FastAPI 1 FastAPI 2 FastAPI 3

二十、Load Balancer 除了分流,還有另一個重要功能:高可用性

假設沒有 Load Balancer,只有一台 Backend:

Browser
   │
   ▼
Backend Server

如果 Backend Server 掛掉:

Backend Server
     X

整個 API 就無法使用。

但如果有三台:

        Load Balancer
        /     |     \
       ▼      ▼      ▼
     API 1  API 2  API 3

就算其中一台故障:

API 1 ✓
API 2 X
API 3 ✓

Load Balancer 可以停止把 Request 傳給 API 2。

流量仍然可以送到:

API 1
API 3

因此系統不一定會完全中斷。

這就是 Load Balancer 在「高可用性」上的另一個重要作用。

二十一、Health Check

Load Balancer 必須知道 Backend 還活著,否則它可能一直把 Request 傳給已經掛掉的機器。

因此通常會設定:

Health Check

例如每隔一段時間檢查:

GET /health

FastAPI 可以提供:

@app.get("/health")
def health_check():
    return {
        "status": "ok"
    }

如果 Server 正常:

200 OK

Load Balancer 就繼續送流量。

如果 Server 一直回:

500

或根本無法連線,Load Balancer 就可以暫時把這台 Server 移出流量池。

概念上就是:

Backend 1 → Healthy
Backend 2 → Unhealthy
Backend 3 → Healthy

因此:

Request
   │
   ▼
Load Balancer
   ├── Backend 1 ✓
   ├── Backend 2 X
   └── Backend 3 ✓

二十二、加入 Load Balancer 後的完整架構

前後端分離再加入 Load Balancer,可以變成:

                         User
                          │
                          ▼
                      Internet
                          │
              ┌───────────┴───────────┐
              │                       │
              ▼                       ▼
      www.example.com          api.example.com
              │                       │
              ▼                       ▼
       Frontend Server         Load Balancer
                                      │
                            ┌─────────┼─────────┐
                            │         │         │
                            ▼         ▼         ▼
                         API 1     API 2     API 3
                            \         │         /
                             \        │        /
                              └───────┼───────┘
                                      │
                                      ▼
                                   Database

這時候各層的責任就會變得很清楚:

Frontend
→ 顯示畫面

Load Balancer
→ 分配 API 流量

Backend
→ 處理商業邏輯

Database
→ 保存資料

二十三、多台 Backend 帶來的新問題

Backend 從一台變成多台之後,雖然解決了效能與單點故障問題,但也會產生新的問題。

例如:

使用者登入
   │
   ▼
Request 1 → Backend 1

假設 Backend 1 把登入狀態存在自己的記憶體裡。

下一個 Request:

Request 2 → Backend 2

Backend 2 並不知道使用者剛才已經登入。

這就會出現問題。

因此多台 Backend 架構通常不能把重要 Session 狀態只存在單一 Backend 的 Memory。

常見做法是把共享狀態放到:

Redis
Database

例如:

                   Load Balancer
                        │
              ┌─────────┴─────────┐
              │                   │
              ▼                   ▼
          Backend 1           Backend 2
              │                   │
              └─────────┬─────────┘
                        │
                        ▼
                      Redis

這樣不管 Request 被分配到哪一台 Backend,都可以取得相同的登入 Session 或 Cache 資料。

因此從一台 Backend 擴充到多台 Backend 之後,系統架構往往也會開始加入 Redis、共享儲存與集中式資料庫等元件。

二十四、部署架構的演進

到這裡,整個部署架構可以整理成:

第一階段:單機部署

Nginx
├── Frontend
├── Backend
└── Database

接著:

第二階段:前後端分離

Frontend Server

Backend Server
     │
     ▼
 Database

再往後:

第三階段:Load Balancer

Frontend
    │
    ▼
Load Balancer
    │
 ┌──┼──┐
 ▼  ▼  ▼
API API API
    │
    ▼
 Database

如果系統再繼續成長,就會逐漸遇到更多部署問題,例如:

Redis
Docker
CI/CD
Container Registry
Auto Scaling
Kubernetes
Cloud Load Balancer

因此 Load Balancer 可以視為從「單機部署」走向「分散式系統」的一個重要分水嶺。


上一篇
前後端分離部署[Day2]
下一篇
多台後端伺服器會遇到狀況與解法[Day4]
系列文
探討k8s部署方式9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言